
#ifndef SRC_USER_FAULT_DIAGNOSE_H_
#define SRC_USER_FAULT_DIAGNOSE_H_

#include "stdint.h"
#include "arm_math.h"

typedef enum
{
    TYPE_FAULT = 0,
    TYPE_WARN  = 1,
    TYPE_EARLY

}ENUM_FLT_TYPE;


typedef enum
{
    FAULT_NOT_LATCH = 0,
    FAULT_LATCH

}ENUM_FLT_LATCH;


typedef enum
{
    DIAG_NORMAL = 0,
    DIAG_NEGATE

}ENUM_DIAG_NEGATE;


typedef struct
{
    float32_t threshold[2];
    float32_t schmidt;
    int16_t fault;
    int16_t warn;
	uint16_t faultcnt;
	uint16_t warncnt;
	uint16_t maxcnt;
    int16_t latch;
    int16_t negate;

}STR_FLT_DIAG;

/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/
static __INLINE void thresholdFltDiag(float32_t value, STR_FLT_DIAG *param, uint16_t runtime_ms)
{
    int16_t thershold_d = param->threshold[0];
    int16_t thershold_w = param->threshold[1];
    int16_t thershold_s = param->schmidt;

    if(param->negate == 1)
    {
        thershold_d = 0 - param->threshold[0];
        thershold_w = 0 - param->threshold[1];
        value       = 0 - value;
    }

    if(((param->fault)) == 0)
    {
        if(value > thershold_d)
        {
			param->faultcnt += runtime_ms;
			
			if(param->faultcnt > param->maxcnt)
			{
				(param->fault) = 1;
				param->faultcnt = param->maxcnt;
			}
        }

        if(value < (thershold_w - thershold_s))
        {
            (param->warn) = 0;
			param->warncnt = 0;
        }

        else if(value > thershold_w)
        {
			param->warncnt += runtime_ms;
			
			if(param->warncnt > param->maxcnt)
			{
				(param->warn) = 1;
				param->warncnt = param->maxcnt;
			}
        }
    }
    else if(param->latch == FAULT_NOT_LATCH)
    {
        if(value < (thershold_d - thershold_s))
        {
            (param->fault) = 0;
			param->faultcnt = 0;
        }
    }
}



static __INLINE void thresholdFltClear(STR_FLT_DIAG *param)
{
	param->fault = 0;
	param->warn  = 0;
	
	param->faultcnt = 0;
	param->warncnt = 0;
}





extern void param_diag_init(void);

#endif 



